import tinycolor from 'tinycolor2'
import { Ref, ref } from 'vue'

export const presetColors = [
  '#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321',
  '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2',
  '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF',
  'rgba(0,0,0,0)',
]

export const PresetColors = [
  {
    value: 'common', label: '通用颜色', colors: [
      'rgba(0,0,0,0)', '#000000', '#FF2525', '#FF6200', '#FCCA00', '#27B148', '#00C7FF', '#3291F8', '#A411D1',
      '#8CA2AA', '#505559', '#FF7272', '#FF9959', '#FEDD59', '#52CC6F', '#59DBFF', '#7AB8FB', '#C465E2',
      '#C1CDD1', '#C2C7CC', '#FFB3B3', '#FFC9A6', '#FEEDA6', '#7EE697', '#A6ECFF', '#B8D9FD', '#E0ACEF',
      '#EDF1F2', '#E1E3E6', '#FFE9E9', '#FFEFE5', '#FFFAE5', '#DDFAE4', '#E5FAFF', '#EBF4FF', '#F6E7FB',
    ],
  },
  {
    value: 'element', label: 'Element', colors: [
      '#409EFF', '#66B1FF', '#79BBFF', '#8CC5FF', '#A0CFFF', '#B3D8FF', '#C6E2FF', '#D9ECFF', '#ECF5FF',
      '#67C23A', '#E1F3D8', '#F0F9EB', '#E6A23C', '#FAECD8', '#FDF6EC', '#F56C6C', '#FDE2E2', '#FEF0F0',
      '#000000', '#303133', '#606266', '#909399', '#C0C4CC', '#DCDFE6', '#E4E7ED', '#EBEEF5', '#F2F6FC',
      '#909399', '#E9E9EB', '#F4F4F5',
    ],
  },
  {
    value: 'antd', label: 'Ant Design', colors: [
      '#fbfbfb', '#F7F7F7', '#F5F5F5', '#E9E9E9', '#D9D9D9', '#BFBFBF', '#919191', '#5A5A5A', '#404040',
      '#FFF1F0', '#FFCCC7', '#FFA39E', '#FF7875', '#FF4D4F', '#F5222D', '#CF1322', '#A8071A', '#820014',
      '#FFF7E6', '#FFE7BA', '#FFD591', '#FFC069', '#FFA940', '#FA8C16', '#D46B08', '#AD4E00', '#873800',
      '#FEFFE6', '#FFFFB8', '#FFFB8F', '#FFF566', '#FFEC3D', '#FADB14', '#D4B106', '#AD8B00', '#876800',
      '#F6FFED', '#D9F7BE', '#B7EB8F', '#95DE64', '#73D13D', '#52C41A', '#389E0D', '#237804', '#135200',
      '#E6FFFB', '#B5F5EC', '#87E8DE', '#5CDBD3', '#36CFC9', '#13C2C2', '#08979C', '#006D75', '#00474F',
      '#E6F7FF', '#BAE7FF', '#91D5FF', '#69C0FF', '#40A9FF', '#1890FF', '#096DD9', '#0050B3', '#003A8C',
      '#F9F0FF', '#EFDBFF', '#D3ADF7', '#B37FEB', '#9254DE', '#722ED1', '#531DAB', '#391085', '#391085',
      '#FFF0F6', '#FFD6E7', '#FFADD2', '#FF85C0', '#F759AB', '#EB2F96', '#C41D7F', '#9E1068', '#780650',
    ],
  },
  {
    value: 'material', label: 'Material Design', colors: [
      '#FF1744', '#F50057', '#D500F9', '#651FFF', '#3D5AFE', '#2979FF', '#00B0FF', '#00E5FF', '#1DE9B6',
      '#00E676', '#76FF03', '#C6FF00', '#FFEA00', '#FFC400', '#FF9100', '#FF3D00', '#212121', '#424242',
      '#616161', '#757575', '#9E9E9E', '#BDBDBD', '#E0E0E0', '#EEEEEE', '#F5F5F5', '#FAFAFA',
    ],
  },
]

const RECENT_COLORS_KEY = 'pe-recent-colors'

export const RECENT_COLORS: Ref<string[]> = ref([])

export function refreshRecentColors() {
  const recentColorsStr = localStorage.getItem(RECENT_COLORS_KEY)
  RECENT_COLORS.value = recentColorsStr ? JSON.parse(recentColorsStr) : []
}

export function addRecentColor(color: string) {
  if (isValidHex(color)) {
    refreshRecentColors()
    const hasIndex = RECENT_COLORS.value.indexOf(color)
    if (hasIndex >= 0) {
      RECENT_COLORS.value.splice(hasIndex, 1)
    }
    RECENT_COLORS.value.unshift(color)
    if (RECENT_COLORS.value.length > 18) {
      RECENT_COLORS.value.splice(18, RECENT_COLORS.value.length - 18)
    }
    localStorage.setItem(RECENT_COLORS_KEY, JSON.stringify(RECENT_COLORS.value))
  }
}


export function _colorChange(data: any, oldHue?: any) {
  const alpha = data && data.a
  let color: tinycolor.Instance

  // hsl is better than hex between conversions
  if (data && data.hsl) {
    color = tinycolor(data.hsl)
  } else if (data && data.hex && data.hex.length > 0) {
    color = tinycolor(data.hex)
  } else if (data && data.hsv) {
    color = tinycolor(data.hsv)
  } else if (data && data.rgba) {
    color = tinycolor(data.rgba)
  } else if (data && data.rgb) {
    color = tinycolor(data.rgb)
  } else {
    color = tinycolor(data)
  }

  if (color && ((color as any)._a === undefined || (color as any)._a === null)) {
    color.setAlpha(alpha || 1)
  }

  const hsl = color.toHsl()
  const hsv = color.toHsv()

  if (hsl.s === 0) {
    hsv.h = hsl.h = data.h || (data.hsl && data.hsl.h) || oldHue || 0
  }

  /* --- comment this block to fix #109, may cause #25 again --- */
  // when the hsv.v is less than 0.0164 (base on test)
  // because of possible loss of precision
  // the result of hue and saturation would be miscalculated
  // if (hsv.v < 0.0164) {
  //   hsv.h = data.h || (data.hsv && data.hsv.h) || 0
  //   hsv.s = data.s || (data.hsv && data.hsv.s) || 0
  // }

  // if (hsl.l < 0.01) {
  //   hsl.h = data.h || (data.hsl && data.hsl.h) || 0
  //   hsl.s = data.s || (data.hsl && data.hsl.s) || 0
  // }
  /* ------ */

  return {
    hsl: hsl,
    hex: color.toHexString().toUpperCase(),
    hex8: color.toHex8String().toUpperCase(),
    rgba: color.toRgb(),
    hsv: hsv,
    oldHue: data.h || oldHue || hsl.h,
    source: data.source,
    a: data.a || color.getAlpha(),
  }
}

export const isValidHex = (hex: any) => {
  return tinycolor(hex).isValid()
}

export const simpleCheckForValidColor = (data: any) => {
  const keysToCheck = ['r', 'g', 'b', 'a', 'h', 's', 'l', 'v']
  let checked = 0
  let passed = 0

  for (let i = 0; i < keysToCheck.length; i++) {
    const letter = keysToCheck[i]
    if (data[letter]) {
      checked++
      if (!isNaN(data[letter])) {
        passed++
      }
    }
  }

  if (checked === passed) {
    return data
  }
}

export const paletteUpperCase = (palette: string[]) => {
  return palette.map(c => c.toUpperCase())
}